/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			mainwindow.h
  \date			Aug 2011
  \author		TNick

  \brief		Contains the definition for MainWindow class


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n
 Please read ReadMe.txt and Licence.txt in root folder @n
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __MAINWINDOW_INC__
#define __MAINWINDOW_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

class       PageMdl;
class       WorkThread;
class       QNetworkReply;
class       PageData;

#include    <QMainWindow>
#include    <QItemSelectionModel>
#ifdef      PREFER_MUTEXES
#include    <QMutex>
#else
#include    <QReadWriteLock>
#endif
#ifndef QT_NO_OPENSSL
#include    <QSslError>
#endif
#include    <QNetworkRequest>
#include    <QNetworkReply>
#include    <QGraphicsScene>


/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

namespace Ui {
class MainWindow;
}

/// form representing the main GUI component
class MainWindow : public QMainWindow		{
	Q_OBJECT
	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */

	friend class GenOpts;

public:

	/// identifies types of web requests
	enum    ReqCommand  {

		REQ_MAIN = 0, /**<  used by the base implementation
	to get the page to scan */
		REQ_WEBPAGE, /**< used to retrieve a web page / resource */

		REQ_MAX
	};

private:
	/** @name flags for this class     */
	//@{

	/// defines various flags valid for flags member
	enum		FLG		{
		NONE = 0,           /**< no flag is set */
		USABLE = 0x0001,	/**< requests arriving at
reply handler are serviced only if this flag is set, otherwise
they are ignored */
		SAVETODISK = 0x0002,/**< the list of pages is saved to disk */
		SAVEPATRN = 0x0004,	/**< only pages matching pattern are saved */
		PAUSED = 0x0008,	/**< the target page is not being searched
at each clock tick; the user can still check the page manually */

		TOPVAL			/**< values above and equal are invalid */
	};

	//@}




	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */


private:

	/// GUI components
	Ui::MainWindow *        ui;


	/// selection model for list of pages
	QItemSelectionModel *   sel_mdl;


	/// the model used with pages
	PageMdl *               pg_mdl;


	/// graphic scene
	QGraphicsScene          scene;

	/// moving icon in scene
	QGraphicsPixmapItem *   mov_icon;


	/** @name flags for this class     */
	//@{

	/// various flags
	FLG             flags;

	//@}



#ifdef      PREFER_MUTEXES
	/// sequential access to resources
	QMutex 		mutex;
#else
	/// sequential access to resources
	QReadWriteLock      rw_lock;
#endif



	/// the distance between two consecutive page checks in miliseconds
	int                 msecs_to_sleep;

	/// the address of the page that is checked
	QString             s_url_to_search;

	/// root address used to form full URIs
	QString             s_url_base;

	/// the name of current job
	QString             s_job_name;

	/// the pattern used to identify a block of text inside the page that is checked
	/**
	  * This is a regular expression that needs to output one item. If this
	  * is empty, the entire page is passed to next step (links identification)
	  * otherwise only the resulted block.
	  */
	QString             s_group_pattern;

	/// pattern used to identify links inside the block
	/**
	  * The output from previous step (block identification) is searched using
	  * this regular expression. First element needs to be the link, second
	  * needs to be the title. It is an error to leave this filed empty.
	  */
	QString             s_url_pattern;


	/// number of pages to keep in the list
	/**
	  * When the number of pages excedes this number, pages are discarded
	  * from the list and from RAM. They may be saved to disk, depending
	  * on the other settings.
	  */
	int                 cached_count;



	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

	/// constructor;
	explicit			MainWindow		(QWidget *parent = 0);

	/// destructor;
	~MainWindow         (void);

	/// export item model
	PageMdl *           pageModel       (void)
	{ return pg_mdl; }

	/// tell the current page
	PageData *          currentPageD    (void);

public slots:

	/// the page is loading
	void        pageLoadStart           (void);

	/// the page has been loaded
	void        pageLoadEnd             (bool b_ok);

	/// url has been changed
	void        pageURLChange           (const QUrl & new_url);

	/// informed about the appending of pages to current stack
	void        slot_NewPagesRecived    (int new_count);



	/// used by the network interface to process finished requests
	void        replyFinished           (QNetworkReply*);

	/// informed about an error in the request; replyFinished() also fires
	void         replyError              (
		QNetworkReply::NetworkError err_code
		);

#ifndef QT_NO_OPENSSL
	/// informed about an SSL error in the request
	void         replySSLError           (
		const QList<QSslError> &    errors
		);
#endif

	/// gets called regullary by the timer to get and scan base page
	void         timerEvent              (void);





private:


	/// save the settings related to WorkerThread
	void                    saveSettings    (void);

	/// blocks the access to internal storage and allows reading
	inline void             readMe      (void)
	{
#ifdef      PREFER_MUTEXES
	mutex.lock();
#else
	rw_lock.lockForRead();
#endif
	}

	/// blocks the access to internal storage and allows reading and writing
	inline void             writeMe     (void)
	{
#ifdef      PREFER_MUTEXES
	mutex.lock();
#else
	rw_lock.lockForWrite();
#endif
	}

	/// releases the blocking set in place by either writeMe() or readMe()
	inline void             unlockMe    (void)
	{
#ifdef      PREFER_MUTEXES
	mutex.unlock();
#else
	rw_lock.unlock();
#endif
	}


	/// the function parses a string and extracts relevenat pages
	/**
   * it is this function that makes use of patterns defined in this class
   */
	void        process_links       (QString s_scan);




	/** @name flags for this class     */
	//@{

	/// set enabled state (on disabled, all requests are ignored)
	inline void     setInterfEnabled          (bool b_set)
	{
		if (b_set) flags = (FLG)(flags | USABLE);
		else flags = (FLG)(flags & (~USABLE));
	}
	/// get enabled state
	inline bool     interfEnabled             (void)
	{ return ((flags & USABLE) != 0); }


	/// decide if the pages are saved on an permanent storage
	inline void     setSaveToDisk       (bool b_set)
	{
		if (b_set) flags = (FLG)(flags | SAVETODISK);
		else flags = (FLG)(flags & (~SAVETODISK));
	}
	/// tell if the pages are saved on an permanent storage
	inline bool     saveToDisk          (void)
	{ return ((flags & SAVETODISK) != 0); }


	/// set only save pages that match the pattern
	inline void     setSavePatternOnly  (bool b_set)
	{
		if (b_set) flags = (FLG)(flags | SAVEPATRN | SAVETODISK);
		else flags = (FLG)(flags & (~SAVEPATRN));
	}
	/// tell which pages get saved to disk
	inline bool     savePatternOnly     (void)
	{ return ((flags & (SAVETODISK | SAVEPATRN)) == (SAVETODISK | SAVEPATRN)); }



	/// start or stop the timer that checks a page on regular basis
	void            setPaused           (bool b_set);

	/// get the status of the timer
	inline bool     paused              (void)
	{ return ((flags & PAUSED) != 0); }

	//@}


	/// actual loading for style sheets
	void    _loadStySh              (QString fileName);

	/// initialization for pre-made components
	void    initPreMade             (void);

	/// initialization for UI templates
	void    initUITemplates         (void);

	/// initialization for UI templates
	void    initSkins               (void);

	/// initialization for UI templates
	void    initToolbars            (void);

	/// the part responsable for download is being started
	void    initWorkingSet          (void);

	/// for now, start only static filters
	void    initFilters             (void);

	/// reimplement close event to allow settings save and clean-up
	void    closeEvent              (QCloseEvent *event);

	/// reimplement change event to allow translations
	void    changeEvent             (QEvent *e);






private slots:

	/// removes the color decoration that may have been previously loaded
	void    slot_No_skin            (void);

	/// loads color decoration from a file (the user needs to browse)
	void    slot_LoadStySh          (void);

	/// toogle layout direction (left to right or reverse)
	void    slot_LayDir             (void);

	/// presents a short message describing the application
	void    slot_About            	(void);

	/// provides access to the help system
	void    slot_Help            	(void);

	/// contextual help for GUI
	void    slot_HelpCtx            (void);

	/// change the template for the GUI
	void    slot_UItplChange        (QAction* p_active);

	/// change the color scheme of the GUI
	void    slot_SkinChange         (QAction* p_active);

	/// change the filtered / unfiltered mode
	void	slot_FilteredChange		(int filt_on);

	/// change the filtered in / filtered out mode
	void	slot_FilterInOutChange	(int filt_on);

	/// show the general options dialog
	void    slot_GenOpts            (void);

	/// show filter options dialog
	void    slot_FiltOpts           (void);

	/// change the scene
	void    slot_Advance            (int i);



	/// copy current item in clipboard
	void    slot_LstCopy            (void);
	/// copy current item's name in clipboard
	void    slot_LstCopyName        (void);
	/// copy current item's address in clipboard
	void    slot_LstCopyAddr        (void);
	/// copy current item's retrieval date in clipboard
	void    slot_LstCopyData        (void);
	/// delete current item
	void    slot_LstDel             (void);
	/// delete all items
	void    slot_LstDelAll          (void);
	/// delete all items
	void    slot_LstDelFIn          (void);
	/// delete all items
	void    slot_LstDelFOut         (void);
	/// show selection in browser
	void    slot_ShowInBrowser      (void);

	/// show selection in browser
	void    slot_LstDblClk          (const QModelIndex & idx_mdl);


	/// informed about user selection in list of pages
	void    slot_PgLstSelChange     (
		const QModelIndex & current, const QModelIndex & previous);

	/// starts or stops the auto refresh
	void    slot_StartStop          (void);

	/// show filter options dialog
	void    slot_RefreshLst         (void);

	/// request to change the page that is displayed in web browser
	void    slot_ReqLoadPage        (void);

	/// context menu for the list
	void    slot_LstCtxMnu          ( const QPoint& pt_of_mnu);


	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//


};	/*	class MainWindow	*/

/*  CLASS    =============================================================== */
//
//
//
//
#endif // __MAINWINDOW_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
